package com.carol.lmsbe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carol.lmsbe.dto.ConsumableConsumptionDTO;
import com.carol.lmsbe.dto.ConsumableReceiveCreateRequest;
import com.carol.lmsbe.dto.ConsumableReceiveDTO;
import com.carol.lmsbe.dto.ConsumableReceiveQueryRequest;
import com.carol.lmsbe.entity.ConsumableItem;
import com.carol.lmsbe.entity.ConsumablePlan;
import com.carol.lmsbe.entity.ConsumableReceive;
import com.carol.lmsbe.entity.Laboratory;
import com.carol.lmsbe.entity.User;
import com.carol.lmsbe.mapper.ConsumableItemMapper;
import com.carol.lmsbe.mapper.ConsumablePlanMapper;
import com.carol.lmsbe.mapper.ConsumableReceiveMapper;
import com.carol.lmsbe.mapper.LaboratoryMapper;
import com.carol.lmsbe.mapper.UserMapper;
import com.carol.lmsbe.security.JwtAuthenticationFilter;
import com.carol.lmsbe.service.ConsumableReceiveService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 易耗品领用服务实现类
 */
@Service
public class ConsumableReceiveServiceImpl implements ConsumableReceiveService {

    @Autowired
    private ConsumableReceiveMapper consumableReceiveMapper;

    @Autowired
    private ConsumableItemMapper consumableItemMapper;

    @Autowired
    private ConsumablePlanMapper consumablePlanMapper;

    @Autowired
    private LaboratoryMapper laboratoryMapper;

    @Autowired
    private UserMapper userMapper;

    @Override
    public Page<ConsumableReceiveDTO> listReceives(ConsumableReceiveQueryRequest request) {
        Page<ConsumableReceive> page = new Page<>(request.getCurrent(), request.getSize());
        
        LambdaQueryWrapper<ConsumableReceive> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(request.getLaboratoryId() != null, ConsumableReceive::getLaboratoryId, request.getLaboratoryId())
                   .eq(request.getReceiverId() != null, ConsumableReceive::getReceiverId, request.getReceiverId())
                   .eq(request.getIsPlanned() != null, ConsumableReceive::getIsPlanned, request.getIsPlanned())
                   .eq(request.getApprovalStatus() != null, ConsumableReceive::getApprovalStatus, request.getApprovalStatus())
                   .ge(request.getReceiveDateStart() != null, ConsumableReceive::getReceiveDate, request.getReceiveDateStart())
                   .le(request.getReceiveDateEnd() != null, ConsumableReceive::getReceiveDate, request.getReceiveDateEnd())
                   .orderByDesc(ConsumableReceive::getCreateTime);

        Page<ConsumableReceive> receivePage = consumableReceiveMapper.selectPage(page, queryWrapper);
        
        Page<ConsumableReceiveDTO> dtoPage = new Page<>(receivePage.getCurrent(), receivePage.getSize(), receivePage.getTotal());
        List<ConsumableReceiveDTO> dtoList = receivePage.getRecords().stream().map(this::convertToDTO).collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }

    @Override
    public ConsumableReceiveDTO getReceiveById(Long id) {
        ConsumableReceive receive = consumableReceiveMapper.selectById(id);
        if (receive == null) {
            throw new RuntimeException("易耗品领用记录不存在");
        }
        
        return convertToDTO(receive);
    }

    @Override
    @Transactional
    public ConsumableReceiveDTO createReceive(ConsumableReceiveCreateRequest request) {
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        JwtAuthenticationFilter.UserPrincipal userPrincipal = (JwtAuthenticationFilter.UserPrincipal) authentication.getPrincipal();
        
        // 获取用户信息
        User user = userMapper.selectById(userPrincipal.getUserId());
        
        // 创建领用记录
        ConsumableReceive receive = new ConsumableReceive();
        receive.setReceiverId(userPrincipal.getUserId());
        receive.setLaboratoryId(user.getLaboratoryId());
        receive.setItemName(request.getItemName());
        receive.setSpecification(request.getSpecification());
        receive.setUnit(request.getUnit());
        receive.setQuantity(request.getQuantity());
        receive.setUnitPrice(request.getUnitPrice());
        receive.setTotalAmount(request.getUnitPrice().multiply(java.math.BigDecimal.valueOf(request.getQuantity())));
        receive.setReceiveDate(request.getReceiveDate());
        receive.setPurpose(request.getPurpose());
        receive.setIsPlanned(request.getIsPlanned());
        receive.setPlanId(request.getPlanId());
        receive.setReceiverName(request.getReceiverName());
        receive.setReceiverPhone(request.getReceiverPhone());
        receive.setRemark(request.getRemark());
        
        consumableReceiveMapper.insert(receive);
        
        return getReceiveById(receive.getId());
    }

    @Override
    @Transactional
    public ConsumableReceiveDTO updateReceive(Long id, ConsumableReceiveCreateRequest request) {
        ConsumableReceive receive = consumableReceiveMapper.selectById(id);
        if (receive == null) {
            throw new RuntimeException("易耗品领用记录不存在");
        }
        
        if (!"PENDING".equals(receive.getApprovalStatus())) {
            throw new RuntimeException("只有待审批状态的记录可以修改");
        }
        
        // 更新记录
        receive.setQuantity(request.getQuantity());
        receive.setUnitPrice(request.getUnitPrice());
        receive.setTotalAmount(request.getUnitPrice().multiply(java.math.BigDecimal.valueOf(request.getQuantity())));
        receive.setReceiveDate(request.getReceiveDate());
        receive.setPurpose(request.getPurpose());
        receive.setIsPlanned(request.getIsPlanned());
        
        consumableReceiveMapper.updateById(receive);
        
        return getReceiveById(receive.getId());
    }

    @Override
    public void deleteReceive(Long id) {
        ConsumableReceive receive = consumableReceiveMapper.selectById(id);
        if (receive == null) {
            throw new RuntimeException("易耗品领用记录不存在");
        }
        
        // 删除领用记录（简化处理，不检查状态）
        
        consumableReceiveMapper.deleteById(id);
    }

    @Override
    @Transactional
    public void approveReceive(Long id, String status, String comment) {
        ConsumableReceive receive = consumableReceiveMapper.selectById(id);
        if (receive == null) {
            throw new RuntimeException("易耗品领用记录不存在");
        }
        
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        JwtAuthenticationFilter.UserPrincipal userPrincipal = (JwtAuthenticationFilter.UserPrincipal) authentication.getPrincipal();
        
        // 简化处理，直接更新记录
        consumableReceiveMapper.updateById(receive);
    }

    @Override
    public Page<ConsumableReceiveDTO> getMyReceives(ConsumableReceiveQueryRequest request) {
        // 获取当前用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        JwtAuthenticationFilter.UserPrincipal userPrincipal = (JwtAuthenticationFilter.UserPrincipal) authentication.getPrincipal();
        
        request.setReceiverId(userPrincipal.getUserId());
        return listReceives(request);
    }

    @Override
    public Page<ConsumableReceiveDTO> getUnpurchasedItems(ConsumableReceiveQueryRequest request) {
        // 查询所有物品（简化处理）
        List<ConsumableItem> items = consumableItemMapper.selectList(null);
        
        // 转换为DTO
        List<ConsumableReceiveDTO> dtoList = items.stream().map(item -> {
            ConsumableReceiveDTO dto = new ConsumableReceiveDTO();
            dto.setItemName(item.getName());
            dto.setSpecification(item.getSpecification());
            dto.setUnit(item.getUnit());
            dto.setUnitPrice(item.getUnitPrice());
            return dto;
        }).collect(Collectors.toList());
        
        Page<ConsumableReceiveDTO> dtoPage = new Page<>(request.getCurrent(), request.getSize(), dtoList.size());
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }

    @Override
    public Page<ConsumableReceiveDTO> getConsumptionStatistics(ConsumableReceiveQueryRequest request) {
        // 查询消耗统计
        return listReceives(request);
    }

    @Override
    public Page<ConsumableConsumptionDTO> getConsumptionQuery(ConsumableReceiveQueryRequest request) {
        Page<ConsumableReceive> page = new Page<>(request.getCurrent(), request.getSize());
        
        LambdaQueryWrapper<ConsumableReceive> queryWrapper = new LambdaQueryWrapper<>();
        if (request.getLaboratoryId() != null) {
            queryWrapper.eq(ConsumableReceive::getLaboratoryId, request.getLaboratoryId());
        }
        if (request.getItemName() != null && !request.getItemName().trim().isEmpty()) {
            queryWrapper.like(ConsumableReceive::getItemName, request.getItemName());
        }
        queryWrapper.orderByDesc(ConsumableReceive::getCreateTime);

        Page<ConsumableReceive> receivePage = consumableReceiveMapper.selectPage(page, queryWrapper);
        
        Page<ConsumableConsumptionDTO> dtoPage = new Page<>(receivePage.getCurrent(), receivePage.getSize(), receivePage.getTotal());
        List<ConsumableConsumptionDTO> dtoList = receivePage.getRecords().stream().map(this::convertToConsumptionDTO).collect(Collectors.toList());
        dtoPage.setRecords(dtoList);
        
        return dtoPage;
    }

    private ConsumableReceiveDTO convertToDTO(ConsumableReceive receive) {
        ConsumableReceiveDTO dto = new ConsumableReceiveDTO();
        BeanUtils.copyProperties(receive, dto);
        
        // 设置实验室名称
        if (receive.getLaboratoryId() != null) {
            Laboratory laboratory = laboratoryMapper.selectById(receive.getLaboratoryId());
            if (laboratory != null) {
                dto.setLaboratoryName(laboratory.getName());
            }
        }
        
            // 设置领用人名称
            if (receive.getReceiverId() != null) {
                User receiver = userMapper.selectById(receive.getReceiverId());
                if (receiver != null) {
                    dto.setReceiverName(receiver.getRealName());
                }
            }

            // 设置审批人名称
            if (receive.getApproverId() != null) {
                User approver = userMapper.selectById(receive.getApproverId());
                if (approver != null) {
                    dto.setApproverName(approver.getRealName());
                }
            }
        
        return dto;
    }

    private ConsumableConsumptionDTO convertToConsumptionDTO(ConsumableReceive receive) {
        ConsumableConsumptionDTO dto = new ConsumableConsumptionDTO();
        BeanUtils.copyProperties(receive, dto);
        
        // 设置实验室名称
        if (receive.getLaboratoryId() != null) {
            Laboratory laboratory = laboratoryMapper.selectById(receive.getLaboratoryId());
            if (laboratory != null) {
                dto.setLaboratoryName(laboratory.getName());
            }
        }
        
        // 设置领用人名称
        if (receive.getReceiverId() != null) {
            User receiver = userMapper.selectById(receive.getReceiverId());
            if (receiver != null) {
                dto.setReceiverName(receiver.getRealName());
                dto.setReceiverPhone(receiver.getPhone());
            }
        }
        
        // 设置实际消耗数据
        dto.setActualQuantity(receive.getQuantity());
        dto.setActualAmount(receive.getTotalAmount());
        dto.setReceiveDate(receive.getReceiveDate().toString());
        
        // 查找对应的计划数据
        if (receive.getPlanId() != null) {
            ConsumablePlan plan = consumablePlanMapper.selectById(receive.getPlanId());
            if (plan != null) {
                dto.setSemester(plan.getSemester());
                
                // 查找计划中的具体物品
                LambdaQueryWrapper<ConsumableItem> itemWrapper = new LambdaQueryWrapper<>();
                itemWrapper.eq(ConsumableItem::getPlanId, plan.getId())
                          .eq(ConsumableItem::getName, receive.getItemName());
                ConsumableItem planItem = consumableItemMapper.selectOne(itemWrapper);
                
                if (planItem != null) {
                    dto.setPlannedQuantity(planItem.getPlannedQuantity());
                    dto.setPlannedAmount(planItem.getTotalAmount());
                    
                    // 计算消耗率
                    if (planItem.getPlannedQuantity() > 0) {
                        double rate = (double) receive.getQuantity() / planItem.getPlannedQuantity() * 100;
                        dto.setConsumptionRate(Math.round(rate * 100.0) / 100.0);
                    } else {
                        dto.setConsumptionRate(0.0);
                    }
                } else {
                    dto.setPlannedQuantity(0);
                    dto.setPlannedAmount(BigDecimal.ZERO);
                    dto.setConsumptionRate(0.0);
                }
            }
        } else {
            // 非计划内消耗
            dto.setPlannedQuantity(0);
            dto.setPlannedAmount(BigDecimal.ZERO);
            dto.setConsumptionRate(0.0);
            dto.setSemester("非计划内");
        }
        
        return dto;
    }
}
